﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using MadLibrary.Net.Http;

namespace MadLibrary.Net.Server
{
    /// <summary>
    /// Holds options of HttpPort which can be used for configuration of WebServer.
    /// </summary>
    public enum HttpPort
    {
        /// <summary>
        /// Represents default HTTP port (80).
        /// </summary>
        Default = 80,

        /// <summary>
        /// Represents extended HTTP port(8080).
        /// </summary>
        Extended = 8080
    }

    /// <summary>
    /// Serves as base for HTTP web servers.
    /// </summary>
    public abstract class WebServer : Server
    {
        /// <summary>
        /// Holds path of directory which can be used as root for selecting files.
        /// </summary>
        public string InitialDirectory { get; set; }

        /// <summary>
        /// Serves as base of web server configuration method for derived web servers.
        /// </summary>
        public WebServer()
            : base(80)
        {
            this.InitialDirectory = "";
        }

        /// <summary>
        /// Serves as base of web server configuration method for derived web servers.
        /// </summary>
        /// <param name="InitDirectory">Specifies directory which can be as root for selecting files.</param>
        public WebServer(string InitDirectory)
            : base(80)
        {
            this.InitialDirectory = InitDirectory;
        }

        /// <summary>
        /// Serves as base of web server configuration method for derived web servers.
        /// </summary>
        /// <param name="port">Specifies port which has to be used for incomming connections listening.</param>
        /// <param name="InitDirectory">Specifies directory which can be as root for selecting files.</param>
        public WebServer(HttpPort port, string InitDirectory)
        {
            if(port == HttpPort.Default)
                this.ListeningPort = (int)port;
            else if(port == HttpPort.Extended)
                this.ListeningPort = (int)port;
            this.InitialDirectory = InitDirectory;
        }

        /// <summary>
        /// Serves as private override which creates new HttpRequest instance, passes it as overridable ProcessRequest method parameter and sends response based on returned instance to client.
        /// </summary>
        /// <param name="client"></param>
#warning Somebody please look at this supression

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        public override void Process(Socket client)
        {
            NetworkStream ns = new NetworkStream(client);
            StreamReader sr = new StreamReader(ns);
            StreamWriter sw = new StreamWriter(ns);

            HttpRequest req = new HttpRequest(sr.ReadToEnd());
            HttpResponse resp = this.ProcessRequest(req);
            sw.WriteLine(resp.Build());

            sr.Close();
            sw.Close();
            ns.Close();
        }

        /// <summary>
        /// Serves as virtual base which has to be overrided for processing requests.
        /// </summary>
        /// <param name="req">Specifies request which was sent by client.</param>
        /// <returns>HttpResponse instance which built string data will be returned to client as response.</returns>
        public virtual HttpResponse ProcessRequest(HttpRequest req)
        {
            return new HttpResponse();
        }

        /// <summary>
        /// Ends web server listening loop.
        /// </summary>
        ~WebServer()
        {
            this.End();
        }
    }
}